﻿namespace Jsl.FxCop
{
    using System;
    using System.Diagnostics;
    using Microsoft.FxCop.Sdk;
    using Microsoft.VisualStudio.TestTools.UnitTesting;

    /// <summary>
    /// Utility assertions that simplify checking FxCop rule results.
    /// </summary>
    public static class ProblemAssert
    {
        /// <summary>
        /// Asserts that the problems has the expected values.
        /// </summary>
        /// <param name="problem">The problem.</param>
        /// <param name="certainty">The certainty.</param>
        /// <param name="fixCategory">The fix category.</param>
        /// <param name="messageLevel">The message level.</param>
        /// <param name="resolution">The resolution.</param>
        [DebuggerHidden]
        public static void AssertMatches(this Problem problem, int certainty, FixCategories fixCategory, MessageLevel messageLevel, string resolution)
        {
            if (problem == null)
            {
                throw new ArgumentNullException("problem");
            }

            Assert.AreEqual(certainty, problem.Certainty, "The Certainty value does not match.");
            Assert.AreEqual(fixCategory, problem.FixCategory, "The FixCategory does not match.");
            Assert.AreEqual(messageLevel, problem.MessageLevel, "The MessageLevel does not match.");
            Assert.AreEqual(resolution, problem.Resolution.ToString(), "The resolutions do not match.");
        }

        /// <summary>
        /// Asserts that there are no problems.
        /// </summary>
        /// <param name="problems">The problems.</param>
        /// <returns>The problems.</returns>
        [DebuggerHidden]
        public static ProblemCollection HasNoMoreProblems(this ProblemCollection problems)
        {
            if (problems == null)
            {
                throw new ArgumentNullException("problems");
            }

            Assert.AreEqual(0, problems.Count, "There are more problems.");

            return problems;
        }

        /// <summary>
        /// Asserts that there is only one problem and that it has the expected values.
        /// </summary>
        /// <param name="problems">The problems.</param>
        /// <param name="certainty">The certainty.</param>
        /// <param name="fixCategory">The fix category.</param>
        /// <param name="messageLevel">The message level.</param>
        /// <param name="resolution">The resolution.</param>
        /// <returns>The problems.</returns>
        [DebuggerHidden]
        public static ProblemCollection HasProblem(this ProblemCollection problems, int certainty, FixCategories fixCategory, MessageLevel messageLevel, string resolution)
        {
            if (problems == null)
            {
                throw new ArgumentNullException("problems");
            }

            Assert.IsTrue(problems.Count > 0, "There are no more problems.");
            problems[0].AssertMatches(certainty, fixCategory, messageLevel, resolution);

            problems.RemoveAt(0);

            return problems;
        }
    }
}